package com.loiot.commons.utils;

import java.util.Map;
import java.util.Set;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.log4j.Logger;

/**
 * Http请求工具类。
 * <p>
 * 
 * @author zhengrunjin
 * @since 0.1
 */
public class HttpUtil {

	private static Logger log = Logger.getLogger(HttpUtil.class);

	/**
	 * 默认编码
	 */
	public static final String DEFAULT_ENCODING = "UTF-8";

	/**
	 * Http客户端。
	 */
	private static HttpClient client = new HttpClient();

	/**
	 * 以GET方式发送一个HTTP请求，当响应状态码为200时将响应内容以字符串返回。
	 * <p>
	 * 此方法采用默认编码{@link #DEFAULT_ENCODING}。
	 * 
	 * @param url
	 *            请求地址。
	 */
	public static String get(String url) {
		return get(url, DEFAULT_ENCODING);
	}

	/**
	 * 以GET方式发送一个HTTP请求，当响应状态码为200时将响应内容以字符串返回。
	 * <p>
	 * 此方法采用指定编码。
	 * 
	 * @param url
	 *            请求地址。
	 * @param encoding
	 *            指定编码。
	 * 
	 * @return http响应内容。<br/>
	 *         当请求失败或url有问题时返回null。
	 */
	public static String get(String url, String encoding) {

		GetMethod method = new GetMethod();

		// 设置编码
		setCharset(method, encoding);

		try {
			// 创建URI对象，解决url字符串中文乱码
			URI uri = new URI(url, true, encoding);
			method.setURI(uri);
		} catch (Exception e) {
			log.error("uri create error.", e);
			return null;
		}

		try {
			// 发送请求
			int statusCode = client.executeMethod(method);
			if (statusCode == 200) {
				// 返回响应内容
				return method.getResponseBodyAsString();
			}
		} catch (Exception e) {
			log.error("execute method error.", e);
		}

		return null;
	}

	/**
	 * 以POST方式发送一个HTTP请求，当响应状态码为200时将响应内容以字符串返回。
	 * <p>
	 * 此方法采用默认编码{@link #DEFAULT_ENCODING}。
	 * 
	 * @param url
	 *            请求地址。
	 * @param data
	 *            请求数据。
	 */
	public static String post(String url, Map<String, Object> data) {
		return post(url, data, DEFAULT_ENCODING);
	}

	/**
	 * 以POST方式发送一个HTTP请求，当响应状态码为200时将响应内容以字符串返回。
	 * <p>
	 * 此方法采用指定编码。目前只不支持文件传输。
	 * 
	 * @param url
	 *            请求地址。
	 * @param data
	 *            请求数据。
	 * @param encoding
	 *            指定编码。
	 * 
	 * @return http响应内容。<br/>
	 *         当请求失败或url有问题时返回null。
	 */
	public static String post(String url, Map<String, Object> data, String encoding) {

		PostMethod method = new PostMethod();

		// 设置编码
		setCharset(method, encoding);

		try {
			// 创建URI对象，解决url字符串中文乱码
			URI uri = new URI(url, true, encoding);
			method.setURI(uri);
		} catch (Exception e) {
			log.error("uri create error.", e);
			return null;
		}

		// 添加参数数据
		for (String key : data.keySet()) {
			method.addParameter(key, StringUtil.toString(data.get(key)));
		}

		try {
			// 发送请求
			int statusCode = client.executeMethod(method);
			if (statusCode == 200) {
				// 返回响应内容
				return method.getResponseBodyAsString();
			}
		} catch (Exception e) {
			log.error("execute method error.", e);
		}

		return null;
	}

	/**
	 * 设置编码。
	 * 
	 * @param method
	 *            http方法。
	 * @param encoding
	 *            编码方式。
	 */
	private static void setCharset(HttpMethod method, String encoding) {
		HttpMethodParams params = method.getParams();
		params.setHttpElementCharset(encoding);
		params.setCredentialCharset(encoding);
		params.setContentCharset(encoding);
	}

}
